package com.yidu.best.bond.bondTrading.service.impl;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.yidu.best.basicSetup.accountset.dao.AccountDao;
import com.yidu.best.basicSetup.accountset.domain.Account;
import com.yidu.best.basicSetup.fundset.dao.FundDao;
import com.yidu.best.basicSetup.fundset.domain.Fund;
import com.yidu.best.bond.bondTrading.dao.BondTradeDao;
import com.yidu.best.bond.bondTrading.domain.BondTrade;
import com.yidu.best.bond.bondTrading.domain.BondTradeVo;
import com.yidu.best.bond.bondTrading.service.BondTradeService;
import com.yidu.best.bond.cashInventory.dao.CashInventoryDao;
import com.yidu.best.bond.cashInventory.domain.CashInventory;
import com.yidu.best.bond.clear.dao.CapitalTransferDao;
import com.yidu.best.bond.clear.domain.CapitalTransfer;
import com.yidu.best.bond.securitiesInventory.dao.SecuritiesInventoryDao;
import com.yidu.best.bond.securitiesInventory.domain.SecuritiesInventory;
import com.yidu.best.util.ExcelUtils;
import com.yidu.best.util.IDUtil;

@Transactional
@Service
public class BondTradeServiceImpl implements BondTradeService {
	@Autowired
	private BondTradeDao bondTradeDao;
	@Autowired
	private CapitalTransferDao capitalTransferDao;
	@Autowired
	private CashInventoryDao cashInventoryDao;
	@Autowired
	private AccountDao accountDao;
	@Autowired
	private SecuritiesInventoryDao securitiesInventoryDao;
	@Autowired
	private FundDao fundDao;

	@Override
	public Map<String, Object> findPageQuery(BondTradeVo bondTradeVo) {
		// 调用dao层方法查询数量
		int count = bondTradeDao.countBondTrade(bondTradeVo);
		// 计算页码
		int page = (bondTradeVo.getPage() - 1) * bondTradeVo.getLimit();
		bondTradeVo.setPage(page);
		// 调用dao层方法分页查询
		List<BondTrade> bondMarketList = bondTradeDao.findPageQuery(bondTradeVo);
		Map<String, Object> map = new HashMap<String, Object>();
		// 将数据存入map中
		map.put("code", 0);
		map.put("count", count);
		map.put("data", bondMarketList);
		return map;

	}

	@Override
	public int insertBondTrade(MultipartFile file) throws IOException {
		File file2 = ExcelUtils.MultipartFileChangeFile(file);
		List<List<Object>> readExcel = ExcelUtils.readExcel(file2);
		// 数据集合
		List<BondTrade> dataList = new ArrayList<BondTrade>();
		int rs = 0;
		for (int i = 1; i < readExcel.size(); i++) {
			// 定义一个集合得到excel表格的数据
			List<Object> objectsd = readExcel.get(i);
			// System.out.println(excelObj.get(i));
			// 定义实体类
			BondTrade bondTraded = new BondTrade();
			// 得到实体类数据字段Id自增长
			bondTraded.setBondTradeId(IDUtil.getUUID());
			// System.out.println(RandomString.generateID());
			// 发行时间tradeDate系统当前时间
			bondTraded.setTradeDate(new Date());
			// 代码
			bondTraded.setBondTradeNo(String.valueOf(objectsd.get(0)));
			// 基金Id
			bondTraded.setFundId(String.valueOf(objectsd.get(1)));
			// 基金编号
			bondTraded.setFundNo(String.valueOf(objectsd.get(2)));
			// 基金名
			bondTraded.setFundName(String.valueOf(objectsd.get(3)));

			// 债券Id
			bondTraded.setBondId(String.valueOf(objectsd.get(4)));
			// 债券编号
			bondTraded.setBondNo(String.valueOf(objectsd.get(5)));
			// 债券名
			bondTraded.setBondName(String.valueOf(objectsd.get(6)));

			// 经理Id
			bondTraded.setUserId(String.valueOf(objectsd.get(7)));
			// 经理
			bondTraded.setUserName(String.valueOf(objectsd.get(8)));

			// 券商Id
			bondTraded.setBrokerId(String.valueOf(objectsd.get(9)));
			// 券商名
			bondTraded.setBrokerName(String.valueOf(objectsd.get(10)));
			// 交易席位Id
			bondTraded.setSeatId(String.valueOf(objectsd.get(11)));
			// 交易席位
			bondTraded.setTradeDeskName(String.valueOf(objectsd.get(12)));
			// 交易方式
			bondTraded.setTradeInOrOut(Integer
					.valueOf(objectsd.get(13).toString().substring(0, (objectsd.get(13).toString().lastIndexOf(".")))));
			// 交易标识
			bondTraded.setTradeFlag(Integer
					.valueOf(objectsd.get(14).toString().substring(0, (objectsd.get(14).toString().lastIndexOf(".")))));
			// 交易价格
			bondTraded.setTradePrice(new BigDecimal(objectsd.get(15).toString()));
			// 交易数量
			bondTraded.setShare(Integer
					.valueOf(objectsd.get(16).toString().substring(0, (objectsd.get(16).toString().lastIndexOf(".")))));
			// 交易额
			bondTraded.setTurnvoer(new BigDecimal(objectsd.get(17).toString()));
			// 印花税
			bondTraded.setStampTax(new BigDecimal(objectsd.get(18).toString()));
			// 征管费
			bondTraded.setManagementFees(new BigDecimal(objectsd.get(19).toString()));
			// 过户费
			bondTraded.setTrabsferFee(new BigDecimal(objectsd.get(20).toString()));
			// 佣金费
			bondTraded.setCommission(new BigDecimal(objectsd.get(21).toString()));
			// 经手费
			bondTraded.setBrokerage(new BigDecimal(objectsd.get(22).toString()));
			// 总金额
			bondTraded.setTotal(new BigDecimal(objectsd.get(23).toString()));
			// 债券利息
			bondTraded.setSecurityInterest(new BigDecimal(objectsd.get(24).toString()));
			// 交易状态
			bondTraded.setTradeStatus(Integer
					.valueOf(objectsd.get(25).toString().substring(0, (objectsd.get(25).toString().lastIndexOf(".")))));
			// 将对象的数据赋值到数据集合
			dataList.add(bondTraded);
		}
		if (dataList != null && !dataList.isEmpty()) {
			// 调用业务方法
			rs = bondTradeDao.insertBondTrade(dataList);
		}
		return rs;
	}

	@Override
	public boolean BondClearing(String bondTradeId, String tradeStatus) {
		int rs = 0, CapitalTransferRs = 0, CachInventoryRs = 0, SecuritiesInventoryRs = 0;
		// 定义数组接受前台返回的字符串数组 将,去掉
		String[] bondTradeIds = bondTradeId.split(",");
		String[] tradeStatuss = tradeStatus.split(",");
		// 将接收的数组遍历
		for (int i = 0; i < bondTradeIds.length; i++) {
			// 将tradeStatus转为Integer类型
			Integer tradeStatus1 = Integer.valueOf(tradeStatuss[i]);
			// 根据bondTradeId查询
			BondTrade bondTrade = bondTradeDao.findBondClearingById(bondTradeIds[i]);
			// 判断状态为0的为未结算
			if (tradeStatus1 == 0) {
				// 调用dao修改状态方法
				rs = bondTradeDao.BondClearing(1, bondTradeIds[i]);
				// 调用添加资金调拨的方法
				CapitalTransferRs = insertCapitalTransfer(bondTrade);
				// 调用修改现金库存的方法
				CachInventoryRs = updateCachInventory(bondTrade);
				// 调用修改证券库存的方法
				SecuritiesInventoryRs = updateSecuritiesInventory(bondTrade);

			} else if (tradeStatus1 == 1) {// 判断状态为1的为已未结算
				// 调用dao层修改状态的方法
				rs = bondTradeDao.BondClearing(0, bondTradeIds[i]);
				// 删除资金调拨表的一条数据
				CapitalTransferRs = deleteCapitalTransfer(bondTradeIds[i]);
				// 调用修改现金库存的方法
				CachInventoryRs = updateCachInventory(bondTrade);
				// 调用修改证券库存的方法
				SecuritiesInventoryRs = updateSecuritiesInventory(bondTrade);
			}
		}
		if (rs >= 1 && CapitalTransferRs >= 1 && CachInventoryRs >= 1 && SecuritiesInventoryRs >= 1) {
			return true;
		} else {
			return false;
		}

	}

	public int insertCapitalTransfer(BondTrade bondTrade) {
		String fundId = bondTrade.getFundId();
		//根据基金id获取基金
		Fund fund = fundDao.findFundById(fundId);
		//根据基金id获取账号
		Account account = accountDao.findAccountById(fund.getAccountId());
		//初始化资金调拨
		CapitalTransfer capitalTransfer = new CapitalTransfer(IDUtil.getUUID(), IDUtil.getNo("ZJDB"),
				bondTrade.getFundId(), bondTrade.getFundNo(), bondTrade.getFundName(), account.getAccountId(),
				account.getAccountNO(), account.getAccountName(), bondTrade.getTotal(), new Date(),
				bondTrade.getTradeFlag(), "债券清算调拨", bondTrade.getBondTradeId());
		return capitalTransferDao.insertCapitalTransfer(capitalTransfer);
	}

	public int deleteCapitalTransfer(String bondTradeId) {
		//根据债券id删除资金调拨表数据
		return capitalTransferDao.deleteCapitalTransfer(bondTradeId);
	}

	public int updateCachInventory(BondTrade bondTrade) {
		CashInventory cashInventory = cashInventoryDao.findCashInventoryIdByFundId(bondTrade.getFundId());
		cashInventory.setStatisticalDate(new Date());
		//旧的现金余额
		BigDecimal oldCashBalance = cashInventory.getCashBalance();
		//新现金余额
		BigDecimal newCashBalance = bondTrade.getTotal();
		if (bondTrade.getTradeStatus() == 0) {// 判断为结算
			// 判断债卷交易类型：
			if (bondTrade.getTradeFlag() == 1) { // 买入
				// 现金减少
				cashInventory.setCashBalance(oldCashBalance.subtract(newCashBalance));
			} else { // 卖出
				cashInventory.setCashBalance(oldCashBalance.add(newCashBalance));
			}
		} else if (bondTrade.getTradeStatus() == 1) {// 判断为反结算
			// 判断债卷交易类型：
			if (bondTrade.getTradeFlag() == 1) {
				// 现金增多
				cashInventory.setCashBalance(oldCashBalance.add(newCashBalance));
			} else { // 现在减少
				cashInventory.setCashBalance(oldCashBalance.subtract(newCashBalance));
			}
		}
		//调用dao层方法修改现金库存
		return cashInventoryDao.updateCachInventory(cashInventory);
	}

	/**
	 * 修改证券库存
	 * 
	 * @param bondTrade
	 * @return
	 */
	private int updateSecuritiesInventory(BondTrade bondTrade) {
		int rs = 0;
		//获取基金id
		String fundId = bondTrade.getFundId();
		//根据基金id查询基金
		Fund fund = fundDao.findFundById(fundId);
		//根据账号id获取账号
		Account account = accountDao.findAccountById(fund.getAccountId());
		//根据基金id和债券id查询证券库存
		SecuritiesInventory securitiesInventory = securitiesInventoryDao
				.findSecuritiesInventoryIdByFundIdandSecuritiesId(bondTrade.getFundId(), bondTrade.getBondId());
		if (bondTrade.getTradeStatus() == 0) {// 判断为结算
			if (securitiesInventory == null) { // 第一次买入
				if(bondTrade.getTradeFlag() == 1) {
					//调用初始化库存方法
					rs = initSecurityInvetory(fund, account, bondTrade);
				}else {
					return rs;
				}
				
			} else { // 第N次买卖
					//调用修改证券库存的方法
					rs = updateSecurityInvetory(bondTrade);
			}
		} else if (bondTrade.getTradeStatus() == 1) {// 判断为反结算
				//调用修改证券库存的方法
				rs = updateSecurityInvetory(bondTrade);
			
		}

		return rs;
	}

	/**
	 * 初始化证券库存
	 * 
	 * @param fund
	 * @param account
	 * @param bondTrade
	 * @return
	 */
	private int initSecurityInvetory(Fund fund, Account account, BondTrade bondTrade) {
		SecuritiesInventory securitiesInventory = new SecuritiesInventory(
				IDUtil.getUUID(), 
				IDUtil.getNo("ZQKC"),
				bondTrade.getBondId(), 
				bondTrade.getBondNo(), 
				bondTrade.getBondName(), 
				fund.getFundId(),
				fund.getFundNo(), 
				fund.getFundName(), 
				account.getAccountId(), 
				account.getAccountNO(),
				account.getAccountName(), 
				bondTrade.getTradePrice(),
				bondTrade.getShare(), 
				bondTrade.getTurnvoer(), 
				2,
				new Date(), null,Integer.valueOf(0));
		//调用dao层方法初始化证券库存
		return securitiesInventoryDao.insertSecuritiesInventory(securitiesInventory);
	}

	/**
	 * 修改证券库存
	 * 
	 * @param bondTrade
	 * @return
	 */
	private int updateSecurityInvetory(BondTrade bondTrade) {
		//根据基金id获取证券库存
		SecuritiesInventory securitiesInventory = securitiesInventoryDao
				.findSecuritiesInventoryIdByFundIdandSecuritiesId(bondTrade.getFundId(),bondTrade.getBondId());
		if(bondTrade.getTradeStatus()==0) {//判断为结算
			if(bondTrade.getTradeFlag() == 1) {//判断为流入
				//证券库存份额+反结算份额
				securitiesInventory.setShare(securitiesInventory.getShare()+bondTrade.getShare());
				//证券库存总金额+结算总金额
				securitiesInventory.setTurnover(securitiesInventory.getTurnover().add(bondTrade.getTurnvoer()));
			}else if(bondTrade.getTradeFlag() == 0){//判断为流出
				//证券库存份额-反结算份额
				securitiesInventory.setShare(securitiesInventory.getShare()-bondTrade.getShare());
				//证券库存总金额-结算总金额
				securitiesInventory.setTurnover(securitiesInventory.getTurnover().subtract(bondTrade.getTurnvoer()));
			}
		}else if(bondTrade.getTradeStatus()==1) {//判断为反结算
			if(bondTrade.getTradeFlag() == 1) {//判断为流入
				//证券库存份额-反结算份额
				securitiesInventory.setShare(securitiesInventory.getShare()-bondTrade.getShare());
				//证券库存总金额-结算总金额
				securitiesInventory.setTurnover(securitiesInventory.getTurnover().subtract(bondTrade.getTurnvoer()));
			}else if(bondTrade.getTradeFlag() == 0){//判断为流出
				//证券库存份额+反结算份额
				securitiesInventory.setShare(securitiesInventory.getShare()+bondTrade.getShare());
				//证券库存总金额+反结算总金额
				securitiesInventory.setTurnover(securitiesInventory.getTurnover().add(bondTrade.getTurnvoer()));
			}
		}
		//获取当前时间
		securitiesInventory.setStatisticalDate(new Date());
		//调用dao层方法
		return securitiesInventoryDao.updateSecuritiesInventory(securitiesInventory);
	}

}
